<script setup>
import {ref, onMounted, onUnmounted, computed, watch, onBeforeUnmount} from "vue";
import ArticleListItem from "@/views/Article/ArticleListItem.vue";
import {EditPen} from '@element-plus/icons-vue';
import {useArticleStore, useUserStore} from "@/stores/index.js";
import {useRoute, useRouter} from "vue-router";
import {articleAPI} from "@/apis/index.js";
import {ElMessage} from "element-plus";

const articleStore = useArticleStore();
const userStore = useUserStore();

const route = useRoute();
const router = useRouter();

const isLoggedIn = computed(() => userStore.isLoggedIn)

// 文章列表信息
const articleList = ref({})
const loading = ref(false)
const pagination = ref({
  totalCount: 0,
  pageSize: 10,
  pageNo: 1,
  pageTotal: 0
})
// 使用store中的响应式状态
const boards = computed(() => articleStore.boards)

// 从路由参数获取板块ID
const pBoardId = computed(() => parseInt(route.params.pBoardId))
const boardId = computed(() => parseInt(route.params.boardId))

// 搜索相关参数
const searchKeyword = computed(() => route.query.keyword)
const searchType = computed(() => route.query.type)
const isSearchMode = computed(() => !!searchKeyword.value)

// 根据当前选择的父板块获取子板块列表
const subBoardList = computed(() => {
  const currentBoard = boards.value.find(board => board.pBoardId === pBoardId.value)
  return currentBoard ? currentBoard.children || [] : []
})

// 文章排序类型
const orderType = ref(0);

// 发帖按钮是否显示
const showFloatingBtn = ref(true);

// 请求控制器，用于取消之前的请求
let currentController = null;

// 获取文章列表
const fetchArticleList = async () => {
  // 进入加载状态，优先显示加载骨架屏，避免空状态闪烁
  loading.value = true
  // 取消之前的请求
  if (currentController) {
    currentController.abort();
  }
  
  // 创建新的请求控制器
  currentController = new AbortController();
  const myController = currentController;
  
  // 立即清空文章列表，避免显示旧数据
  articleList.value = [];
  let data = {}
  
  if (isSearchMode.value) {
    // 搜索模式
    data = {
      pageNo: pagination.value.pageNo,
      pageSize: pagination.value.pageSize,
      keyword: searchKeyword.value,
      searchType: searchType.value == 'title' ? 0 : 1,
    }
  } else {
    // 普通板块模式
    data = {
      pageNo: pagination.value.pageNo,
      pageSize: pagination.value.pageSize,
      pBoardId: pBoardId.value,
      boardId: boardId.value,
      orderType: orderType.value,
    }
  }
  
  loading.value = true
  try {
    let response
    if (isSearchMode.value) {
      response = await articleAPI.searchArticles(data, { signal: currentController.signal })
    } else {
      response = await articleAPI.getArticleList(data, { signal: currentController.signal })
    }
    
    if (response.status === 'success') {
      articleList.value = response.data.list
      pagination.value = {
        pageNo: response.data.pageNo,
        pageSize: response.data.pageSize,
        totalCount: response.data.totalCount,
        pageTotal: response.data.pageTotal
      }
    }
  } catch (error) {
    // 如果是请求被取消，不显示错误信息
    if (error.name === 'AbortError' || error.code === 'ERR_CANCELED') {
      return;
    }
    console.log(error)
  } finally {
    // 仅在当前请求仍是最新请求时结束加载状态
    if (currentController === myController) {
      loading.value = false
    }
  }
}

// 监听路由参数变化，重新加载文章
watch([pBoardId, boardId, searchKeyword, searchType], () => {
  // 重置分页到第一页
  pagination.value.pageNo = 1
  fetchArticleList()
}, {immediate: true})

// 监听pBoardId变化
watch(pBoardId, async (newPBoardId) => {
  if (newPBoardId && boards.value.length === 0) {
    await articleStore.fetchBoards()
  }
}, {immediate: true})

// 改变文章排序类型
const changeOrderType = (type) => {
  orderType.value = type
  fetchArticleList()
}

// 处理分页页数变化
const handlePageChange = (pageNo) => {
  pagination.value.pageNo = pageNo
  fetchArticleList()
}

// 发帖按钮点击事件
const handleCreatePost = () => {
  console.log('点击发帖按钮');
  router.push('/newPost')
}

// 滚动监听函数
const handleScroll = () => {
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  const windowHeight = window.innerHeight;
  const documentHeight = document.documentElement.scrollHeight;

  // 计算底部区域
  const bottomThreshold = 200;
  const isNearBottom = scrollTop + windowHeight >= documentHeight - bottomThreshold;

  // 如果接近底部，隐藏按钮；否则显示按钮
  showFloatingBtn.value = !isNearBottom;
}

// 组件挂载时添加滚动监听
onMounted(() => {
  window.addEventListener('scroll', handleScroll);
});

// 组件卸载时移除滚动监听
onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll);
});

// 组件卸载前取消未完成的请求
onBeforeUnmount(() => {
  if (currentController) {
    currentController.abort();
  }
});
</script>

<template>
  <div class="container-body article-list-body">
    <!-- 搜索结果标题 -->
    <div class="search-header" v-if="isSearchMode">
      <div class="search-info">
        <h2>Search Result</h2>
        <p>Keyword: "{{ searchKeyword }}" | Search Type: {{ searchType }}</p>
      </div>
    </div>

    <div class="sub-board" v-if="pBoardId && !isSearchMode">
      <span :class="['board-item', isNaN(boardId) ? 'active' : '']">
        <router-link :to="`/board/${pBoardId}`">All</router-link></span
      >
      <span
          v-for="item in subBoardList"
          :class="['board-item', item.boardId == boardId ? 'active' : '']"
      >
        <router-link :to="`/board/${pBoardId}/${item.boardId}`">
          {{ item.boardName }}
        </router-link>
      </span>
    </div>

    <div class="article-panel">
      <div class="top-tab" v-if="!isSearchMode">
        <div
            :class="['tab', orderType == 0 ? 'active' : '']"
            @click="changeOrderType(0)"
        >
          Latest
        </div>
        <el-divider direction="vertical"></el-divider>
        <div
            :class="['tab', orderType == 1 ? 'active' : '']"
            @click="changeOrderType(1)"
        >
          Most Like
        </div>
        <el-divider direction="vertical"></el-divider>
        <div
            :class="['tab', orderType == 2 ? 'active' : '']"
            @click="changeOrderType(2)"
        >
          Most Comment
        </div>
      </div>
      <div class="article-list">
        <div class="skeleton" v-if="loading">
          <el-skeleton :row="3" animated></el-skeleton>
        </div>
        <template v-else>
          <template v-if="articleList.length > 0">
            <div v-for="item in articleList">
              <ArticleListItem :data="item"></ArticleListItem>
            </div>
            <div class="pagination" v-if="pagination.pageTotal > 1">
              <el-pagination
                  background
                  :total="pagination.totalCount"
                  v-model:current-page="pagination.pageNo"
                  layout="prev, pager, next"
                  style="text-align: right"
                  :page-size="pagination.pageSize"
                  @current-change="handlePageChange"
              ></el-pagination>
            </div>
          </template>
          <template v-else>
            <el-empty description="There are no posts yet" />
          </template>
        </template>
      </div>
    </div>

    <!-- 悬浮发帖按钮 -->
    <transition name="fade" mode="out-in">
      <el-button
          v-if="isLoggedIn && showFloatingBtn"
          type="primary"
          size="large"
          class="floating-post-btn"
          @click="handleCreatePost"
      >
        <el-icon>
          <EditPen/>
        </el-icon>
        <span>Post</span>
      </el-button>
    </transition>
  </div>
</template>

<style scoped lang="scss">
.article-list-body {
  position: relative;
  width: 1300px;

  .sub-board {
    padding: 10px 0px 12px 0px;

    .board-item {
      background: #fff;
      border-radius: 5px;
      padding: 2px 10px;
      margin-right: 10px;
      color: #909090;
      cursor: pointer;
      font-size: 14px;

      a {
        text-decoration: none;
        color: #909090;
      }
    }

    .active {
      background: var(--link);

      a {
        color: #fff;
      }
    }
  }

  .search-header {
    background: #fff;
    padding: 20px;
    margin-bottom: 10px;
    border-radius: 5px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

    .search-info {
      h2 {
        margin: 0 0 10px 0;
        color: #333;
        font-size: 24px;
      }

      p {
        margin: 0;
        color: #666;
        font-size: 14px;
      }
    }
  }

  .article-panel {
    background: #fff;

    .top-tab {
      display: flex;
      align-items: center;
      padding: 10px 15px;
      font-size: 15px;
      border-bottom: 1px solid #ddd;

      .tab {
        cursor: pointer;
      }

      .active {
        color: var(--link);
      }
    }

    .article-list {
      .skeleton {
        padding: 20px;
      }

      .pagination {
        padding: 10px 0px 10px 10px;
      }
    }
  }
}

/* 悬浮发帖按钮样式 */
.floating-post-btn {
  position: fixed;
  bottom: 80px;
  right: calc(50% - 620px);
  width: 150px;
  height: 60px;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1001;
  font-size: 24px;
}

/* 当屏幕宽度小于1300px时，按钮位置调整 */
@media (max-width: 1300px) {
  .floating-post-btn {
    right: 30px;
  }
}

.floating-post-btn:hover {
  transform: scale(1.1);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease-in-out;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}

.fade-enter-from {
  opacity: 0;
  transform: scale(0.8) translateY(20px);
}

.fade-leave-to {
  opacity: 0;
  transform: scale(0.8) translateY(20px);
}

</style>